#ifndef CHOLDEMHAND_H
#define CHOLDEMHAND_H

#include "hand.h"

//*************************************************************************************************
//  
//  This class is used to figure out the best 5 card hand that can be made out 
//  of a pool of 7 cards.  Once the best 5 card hand is found, other information 
//  can then be extracted about that hand.
//
//  kharmon.  09-28-05.  #5861.
//
//*************************************************************************************************
class CHoldemHand : public Hand
{
public:
    CHoldemHand(CardMgr* Mgr, Hand *pCommunity);

    // this function examines the available cards and pulls out the best 5 card hand
	bool8 rankHand(bool bUseRiver = true);

    // returns the rank of the best 5 card hand
	int32 getRank();

    // looks at the best hand and figures out the Nth highest card, 
	void calcNthHighest(int32 n);

    // returns the value calculated by "calcNthHighest".
	uint8 getHighCard();

    // returns true if this hand meets the minimum requirements needed for the
    // dealer to continue...currently a pair of 4's.
	bool8 qualifies();

    // encodes the rank of the best 5 card hand into Buf.
	int32 outrank(uint8* Buf);

    // encodes the deciding high card from the best 5 card hand into buf.
	int32 outhigh(uint8* Buf);

    // returns the best 5 card hand.
    Hand *getBestHand() { return &m_bestHand; }


private:

    // used by calcNthHighest to do the real work.
	uint8 getNthHighest(int32, int32);

    // check to see if there's 4 of a kind in the 7 available cards.
	bool  checkFourOfAKind(Hand& workingHand, uint8 abyRankCounts[13]);

    // check to see if there's a flush in the 7 available cards.
	bool  checkFlush(Hand& workingHand, uint8 abyRankCounts[13], uint8 abySuitCounts[4]);

    // check to see if there's a straight in the 7 available cards.
    bool  checkStraight(Hand& workingHand, uint8 abyRankCounts[13]);

    // check to see if there's a straight flush in the 7 available cards.
    bool  checkStraightFlush(Hand& workingHand, int nSuit, uint8 abyRankCounts[13]);

    // check to see if there's 3 of a kind in the 7 available cards.
    bool  checkThreeOfAKind(Hand& workingHand, uint8 abyRankCounts[13]);

    // check to see if there's 1 or 2 pairs in the 7 available cards.
    bool  checkPairs(Hand& workingHand, uint8 abyRankCounts[13]);

    //  figure out the 5 best cards by rank out of the 7 available cards.
    void  processHighCard(Hand& workingHand, uint8 abyRankCounts[13]);


    Hand  *m_pCommunity;        // the pool of community cards that will be added to the 2 card hand.
	uint8 m_abyRankCounts[13];  // 2:index 0, 3:index 1 ... A:index 12
	uint8 m_byHighCard;         // the highest decisive card.
	int32 m_nHandRank;          // the final rank of the best 5 card hand.

    Hand  m_bestHand;           // rankHand populates this with the best 5 card hand out of all hands that can be made from the 7 available cards.
};



#endif
